
#include <BlittableImage.h>

#include <cassert>

/**
\author Zachary Wartell
\brief Construct this BlittableImage loading from a image file.

\todo generalize BlittableImage class to allow changing the file being loaded...
*/
BlittableImage::BlittableImage()
    {
    /* 
    Generate texture object and load image file onto GPU
    */
    glGenTextures(1,&textureObject_);
    glBindTexture(GL_TEXTURE_2D,textureObject_);
    	
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    BYTE* bits;
    FIBITMAP *image(nullptr);
    LoadTexture("data/Mia-Cat.jpg",image,width_,height_,bits);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,width_,height_,0,GL_BGR,GL_UNSIGNED_BYTE,bits);

    //Free FreeImage's copy of the data (currently we don't have any reason to keep it allocated)
    FreeImage_Unload(image);

    /*
    Attached the texture to framebuffer object (to allow later blit operation)
    */
    glGenFramebuffers(1,&frameBufferObject_);    
    glBindFramebuffer(GL_READ_FRAMEBUFFER,frameBufferObject_);
    
    glFramebufferTexture(GL_READ_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,textureObject_,0);        
    assert(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));

    glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
    }

/** 
\author Zachary Wartell
\brief Load image file from file 'filename' into a FreeImage object *image.  Also, return the image size (\a width and \a height) and a direct pointer to the memory 
storing the image (\a bits).

\a width and \a height and \a bits can be used with OpenGL functions such as glTexImage2D.  It is the calling function's responsiblity to deallocate *image whenever appropropriate.
Again, \a bits is a pointer to the internal structure of *image so the life-time of bits is controlled by descruction of *image.

REFERENCES:
- code modified from TextureManage.c in FreeImage distribution Examples\OpenGL
**/
bool BlittableImage::LoadTexture
	(
	const char* filename,  // IN: name of file to load
	FIBITMAP* &image,      // OUT: image
	unsigned int& width,   // OUT: width of loaded image 
	unsigned int& height,  // OUT: height of loaded image 
	BYTE* & bits	       // OUT: raw bytes of image (pointer points to storage in the '*image')	
	)
    {
    //image format
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    //check the file signature and deduce its format
    fif = FreeImage_GetFileType(filename, 0);
    //if still unknown, try to guess the file format from the file extension
    if(fif == FIF_UNKNOWN) 
	fif = FreeImage_GetFIFFromFilename(filename);
    //if still unkown, return failure
    if(fif == FIF_UNKNOWN)
	return false;

    //check that the plugin has reading capabilities and load the file
    if(FreeImage_FIFSupportsReading(fif))
	image = FreeImage_Load(fif, filename);
    //if the image failed to load, return failure
    if(!image)
	return false;

    //retrieve the image data
    bits = FreeImage_GetBits(image);
    //get the image width and height
    width = FreeImage_GetWidth(image);
    height = FreeImage_GetHeight(image);
    //if this somehow one of these failed (they shouldn't), return failure
    if((bits == 0) || (width == 0) || (height == 0))
	return false;
    return true;
    }



